--modul zarzadzajacy, ustawia sygnaly sterujace blokow we/wy w odpowiednich momentach czasowych i inicjuje operacje mnozenia
 
library ieee;
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 

entity boz is
	port (	clk : in std_ulogic; --bit zegara
       we_ok, wy_ok : in std_ulogic; --bity startu podawane na blok wejsciowy i wyjsciowy
       we_go, wy_go : out std_ulogic := '0'; --bity gotowosci podawane z bloku wejsciowego i wyjsciowego
       	       we_d : in std_ulogic_vector ( 7 downto 0 ); --wejscie danych z bloku wejsciowego
	       wy_d : out std_ulogic_vector ( 7 downto 0 ) := x"00"; --wyjscie danych na bloku wyjsciowy
	       u2_d : out std_ulogic_vector ( 7 downto 0 ) := x"00"; --ostatnio wprowadzona liczba wyswietlana na diodach led
	       l2_d : out std_ulogic := '1' --bit przepelnienia wyswietlany na diodzie led
	);
end entity boz;

architecture bozarch of boz is 

	component mnoz is	--komponent okreslajacy sygnaly modulu wykonujacego operacje mnozenia
		port (	clk : in std_ulogic;
		    mnoz_go : in std_ulogic;
		     mnoz_a : in std_ulogic_vector ( 7 downto 0);
		     mnoz_b : in std_ulogic_vector ( 7 downto 0);
		    mnoz_ok : out std_ulogic;
		    mnoz_wy : out std_ulogic_vector ( 7 downto 0);
		  mnoz_prze : out std_ulogic
		);
	end component mnoz  ;

	type stan_type is (s0, s1, s2, s3,s4,s5,s6,s7);
	signal stan, stan_akt : stan_type;	--sygnal okreslajacy stan automatu
	signal twe_go, twy_go, tmnoz_go : std_ulogic := '0'; --sygnaly tymczasowych wartosci bitow gotowosci wynikow pracy modulow
	signal la : std_ulogic_vector ( 7 downto 0):= x"00"; --sygnal wewenetrzny okreslajacy mnoznik
	signal lb : std_ulogic_vector ( 7 downto 0):= x"00"; --sygnal wewenetrzny okreslajacy mnozna
	signal wy : std_ulogic_vector ( 7 downto 0):= x"00"; --sygnal wewenetrzny okreslajacy wynik mnozenia
	signal mnoz_ok, mnoz_go, mnoz_prze : std_ulogic := '0';	--sygnaly startu, gotowosci i przepelnienia z modulu mnozenia  
	signal mnoz_a, mnoz_b: std_ulogic_vector ( 7 downto 0):= x"00"; --sygnal mnoznika i mnoznej
	signal mnoz_wy : std_ulogic_vector ( 7 downto 0):= x"00"; --sygnal wyniku mnozenia

	begin
	      e0: mnoz port map (clk,mnoz_go,mnoz_a,mnoz_b,mnoz_ok,mnoz_wy,mnoz_prze);--przylaczenie bloku wykonujacego operacje mnozenia

 	      stan_nast : process (we_ok, wy_ok, mnoz_ok, stan_akt) is
	      begin

		case stan_akt is 
			when s0 => 
				twe_go <= '1'; twy_go <= '0'; tmnoz_go <= '0';
				if (we_ok = '1') then	--czekamy na sygnal startu z bloku wejsciowego
					la <= we_d;	--wtedy zapisujemy dane wejsciowe
					u2_d <= we_d;	--prezentujemy je na diodach led
					stan <= s1;	--i zmieniamy stan
				else
					stan <= s0;
				end if;
			when s1 =>
				twe_go <= '0'; twy_go <= '0'; tmnoz_go <= '0';
				la <= la;
				if (we_ok = '0') then	--czekamy na zakonczenie wpisywania pierwszej liczby
					stan <= s2;
				else
					stan <= s1;
				end if;
			when s2 => 
				twe_go <= '1'; twy_go <= '0'; tmnoz_go <= '0';
				la <= la;
				if (we_ok = '1') then	--gdy pierwsza liczba wczytana to czekamy na druga liczbe
					lb <= we_d;	--zapisujemy ja w zmiennej wewnetrznej
					u2_d <= we_d;	--wyswietlamy na diodach led
					stan <= s3;	--i zmieniamy stan
				else
					stan <= s2;
				end if;
			when s3 => 
				twe_go <= '0'; twy_go <= '0'; tmnoz_go <= '0';
				la <= la;
				lb <= lb;
				if (we_ok = '0') then	--czekamy na zakonczenie wpisywania drugiej liczby
					stan <= s4;
				else
					stan <= s3;
				end if;
			when s4 => 
				twe_go <= '0'; twy_go <= '0'; tmnoz_go <= '1'; --inicjujemy operacje mnoznie ustawiajac bit startu
				la <= la;
				lb <= lb;
				if (mnoz_ok = '1') then	--gdy pojawi sie wynik mnozenia
					wy <= mnoz_wy;	--zapisyjemy wynik
					stan <= s5;
				else
					stan <= s4;
				end if;
			when s5 => 
				twe_go <= '0'; twy_go <= '0'; tmnoz_go <= '0';
				wy <= wy;
				if (mnoz_ok = '0') then --czekamy na zakonczenia dzialania modulu mnozacego
					stan <= s6;
				else
					stan <= s5;
				end if;
			when s6 => 
				twe_go <= '0'; twy_go <= '1'; tmnoz_go <= '0'; --inicjujemy prace bloku wyjsciowego
				if (wy_ok = '1') then	--czekamy na zakonczenie jego dzialania
					stan <= s7;
				else
					stan <= s6;
				end if;
			when s7 =>
				twe_go <= '0'; twy_go <= '0'; tmnoz_go <= '0';
				if (wy_ok = '0') then	--gdy zakonczy sie dzialanie bloku wyjsciowego 
					stan <= s0;	--to czekamy na wprowadzenie kolejnych liczb do pomnozenia
				else
					stan <= s7;
				end if;
		end case; 
    	      end process stan_nast; 
	
	      stan_takt : process (clk) is
		begin
		if rising_edge(clk) then --za kazdym taktem zegara 		
			l2_d <= mnoz_prze; --bit przeniesienia prezentowany na diodzie led
			we_go <= twe_go;   --wartosci tymczasowe przepisywane do wlasciwych zmiennych
			wy_go <= twy_go;
			mnoz_go <= tmnoz_go;
			stan_akt <= stan; --zapisywane zmiany stanu
			mnoz_a <= la;	--aktualizowane dane do bloku mnozenia
			mnoz_b <= lb;
			wy_d <= wy;	--aktalizowane dane do bloku wyjsciowego
		end if;
	      end process stan_takt;

end architecture bozarch; 
